<!doctype html><html lang=zh-cn dir=ltr>
<head><meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1"><meta name=description content="稍微谈一下现在的前端构建学到的一些东西.
打包器 这个东西本身的功能是比较单纯的, 就是将工程的整个依赖图画出来, 然后打包到单个文件里面去.
比较主流的就是Webpack, 其他还有sonwnpack, rollup(这个稍微有点特别), Parcel, 最后还有最近新出现的vite.
优化: 例如压缩Js, CSS, HTML, 摇树, 调整图像大小, 以及分包等机制.所有的优化基本都是为了能在打开网站时更快的载入页面.
扩展: 前端的技术鱼龙混杂, 光开发语言的衍生亚种就非常多, 打包器就需要能支持这些语言的编译器. 部分代码优化也在这里完成. 扩展性基本决定了一个打包器的命运和社区发展.
这两点基本所有的打包器都支持. 接下来说一些有差异化的地方.
Webpack 究极老牌的打包器了, Webpack在5版本之前是出了名的重和慢还有繁, 扩展性和社区都极佳, 基本所有的前端技术你都能在wp上找到对应的loader或者plugin. 也是目前最流行的打包器了. Webpack5出现了之后速度提升了很多. webpack-chain和webpack-merge使用这两个第三方包配合可以做到大部分的配置复用. 但是配置依然很重和繁琐这一点, 一直都没有很好的方案.
var webpack = require(&amp;#39;webpack&amp;#39;); module.exports = {  entry:&amp;#39;./entry.js&amp;#39;, //入口文件  output:{  //node.js中__dirname变量获取当前模块文件所在目录的完整绝对路径  path: &amp;#34;dist&amp;#34;, //输出位置  filename:&amp;#39;bundle.js&amp;#39; //输入文件  },  module:{  loaders:[  {  test:/\.css$/,//支持正则  loader:&amp;#39;style-loader!css-loader&amp;#39;  },   {  test: /\."><title>关于前端构建的碎碎念</title><link rel=canonical href=https://sdttttt.github.io/blog/2022-3-9/>
<link rel=stylesheet href=/scss/style.min.b80bf249ce4a22cf55e8d7340a0b37a2f2c10f54f3a9a49cb94b694a2eb0bbea.css><meta property="og:title" content="关于前端构建的碎碎念">
<meta property="og:description" content="稍微谈一下现在的前端构建学到的一些东西.
打包器 这个东西本身的功能是比较单纯的, 就是将工程的整个依赖图画出来, 然后打包到单个文件里面去.
比较主流的就是Webpack, 其他还有sonwnpack, rollup(这个稍微有点特别), Parcel, 最后还有最近新出现的vite.
优化: 例如压缩Js, CSS, HTML, 摇树, 调整图像大小, 以及分包等机制.所有的优化基本都是为了能在打开网站时更快的载入页面.
扩展: 前端的技术鱼龙混杂, 光开发语言的衍生亚种就非常多, 打包器就需要能支持这些语言的编译器. 部分代码优化也在这里完成. 扩展性基本决定了一个打包器的命运和社区发展.
这两点基本所有的打包器都支持. 接下来说一些有差异化的地方.
Webpack 究极老牌的打包器了, Webpack在5版本之前是出了名的重和慢还有繁, 扩展性和社区都极佳, 基本所有的前端技术你都能在wp上找到对应的loader或者plugin. 也是目前最流行的打包器了. Webpack5出现了之后速度提升了很多. webpack-chain和webpack-merge使用这两个第三方包配合可以做到大部分的配置复用. 但是配置依然很重和繁琐这一点, 一直都没有很好的方案.
var webpack = require(&amp;#39;webpack&amp;#39;); module.exports = {  entry:&amp;#39;./entry.js&amp;#39;, //入口文件  output:{  //node.js中__dirname变量获取当前模块文件所在目录的完整绝对路径  path: &amp;#34;dist&amp;#34;, //输出位置  filename:&amp;#39;bundle.js&amp;#39; //输入文件  },  module:{  loaders:[  {  test:/\.css$/,//支持正则  loader:&amp;#39;style-loader!css-loader&amp;#39;  },   {  test: /\.">
<meta property="og:url" content="https://sdttttt.github.io/blog/2022-3-9/">
<meta property="og:site_name" content="SDTTTTT">
<meta property="og:type" content="article"><meta property="article:section" content="Blog"><meta property="article:tag" content="build"><meta property="article:published_time" content="2022-03-09T16:38:31+08:00"><meta property="article:modified_time" content="2022-03-10T14:46:13+08:00">
<meta name=twitter:title content="关于前端构建的碎碎念">
<meta name=twitter:description content="稍微谈一下现在的前端构建学到的一些东西.
打包器 这个东西本身的功能是比较单纯的, 就是将工程的整个依赖图画出来, 然后打包到单个文件里面去.
比较主流的就是Webpack, 其他还有sonwnpack, rollup(这个稍微有点特别), Parcel, 最后还有最近新出现的vite.
优化: 例如压缩Js, CSS, HTML, 摇树, 调整图像大小, 以及分包等机制.所有的优化基本都是为了能在打开网站时更快的载入页面.
扩展: 前端的技术鱼龙混杂, 光开发语言的衍生亚种就非常多, 打包器就需要能支持这些语言的编译器. 部分代码优化也在这里完成. 扩展性基本决定了一个打包器的命运和社区发展.
这两点基本所有的打包器都支持. 接下来说一些有差异化的地方.
Webpack 究极老牌的打包器了, Webpack在5版本之前是出了名的重和慢还有繁, 扩展性和社区都极佳, 基本所有的前端技术你都能在wp上找到对应的loader或者plugin. 也是目前最流行的打包器了. Webpack5出现了之后速度提升了很多. webpack-chain和webpack-merge使用这两个第三方包配合可以做到大部分的配置复用. 但是配置依然很重和繁琐这一点, 一直都没有很好的方案.
var webpack = require(&amp;#39;webpack&amp;#39;); module.exports = {  entry:&amp;#39;./entry.js&amp;#39;, //入口文件  output:{  //node.js中__dirname变量获取当前模块文件所在目录的完整绝对路径  path: &amp;#34;dist&amp;#34;, //输出位置  filename:&amp;#39;bundle.js&amp;#39; //输入文件  },  module:{  loaders:[  {  test:/\.css$/,//支持正则  loader:&amp;#39;style-loader!css-loader&amp;#39;  },   {  test: /\.">
</head><body class=article-page>
<script>(function(){const e="StackColorScheme";localStorage.getItem(e)||localStorage.setItem(e,"auto")})()</script><script>(function(){const t="StackColorScheme",e=localStorage.getItem(t),n=window.matchMedia("(prefers-color-scheme: dark)").matches===!0;e=="dark"||e==="auto"&&n?document.documentElement.dataset.scheme="dark":document.documentElement.dataset.scheme="light"})()</script>
<div class="container main-container flex on-phone--column compact"><aside class="sidebar left-sidebar sticky">
<button class="hamburger hamburger--spin" type=button id=toggle-menu aria-label="Toggle Menu">
<span class=hamburger-box>
<span class=hamburger-inner></span>
</span>
</button>
<header>
<figure class=site-avatar>
<a href=/>
<img src=/img/avatar_hu8e30117ca872857dd9f41f234a693048_441529_300x0_resize_box_3.png width=300 height=300 class=site-logo loading=lazy alt=Avatar>
</a>
</figure><div class=site-meta>
<h1 class=site-name><a href=/>SDTTTTT</a></h1><h2 class=site-description>臭鱼烂虾</h2></div></header><ol class=menu id=main-menu>
<div class=menu-bottom-section>
<li id=dark-mode-toggle><svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-toggle-left" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentcolor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><circle cx="8" cy="12" r="2"/><rect x="2" y="6" width="20" height="12" rx="6"/></svg><svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-toggle-right" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentcolor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><circle cx="16" cy="12" r="2"/><rect x="2" y="6" width="20" height="12" rx="6"/></svg>
<span>Dark Mode</span>
</li></div></ol></aside><main class="main full-width">
<article class=main-article>
<header class=article-header>
<div class=article-details>
<div class=article-title-wrapper>
<h2 class=article-title>
<a href=/blog/2022-3-9/>关于前端构建的碎碎念</a>
</h2></div><footer class=article-time>
<div><svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-calendar-time" width="56" height="56" viewBox="0 0 24 24" stroke-width="2" stroke="currentcolor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><path d="M11.795 21H5a2 2 0 01-2-2V7a2 2 0 012-2h12a2 2 0 012 2v4"/><circle cx="18" cy="18" r="4"/><path d="M15 3v4"/><path d="M7 3v4"/><path d="M3 11h16"/><path d="M18 16.496V18l1 1"/></svg>
<time class=article-time--published>Mar 09, 2022</time>
</div><div><svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-clock" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentcolor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><circle cx="12" cy="12" r="9"/><polyline points="12 7 12 12 15 15"/></svg>
<time class=article-time--reading>
2 minute read
</time>
</div></footer></div></header><section class=article-content>
<p>稍微谈一下现在的前端构建学到的一些东西.</p><h2 id=打包器>打包器</h2><p>这个东西本身的功能是比较单纯的, 就是将工程的整个依赖图画出来, 然后打包到单个文件里面去.</p><p>比较主流的就是Webpack, 其他还有sonwnpack, rollup(这个稍微有点特别), Parcel, 最后还有最近新出现的vite.</p><p><code>优化</code>: 例如压缩Js, CSS, HTML, 摇树, 调整图像大小, 以及分包等机制.所有的优化基本都是为了能在打开网站时更快的载入页面.</p><p><code>扩展</code>: 前端的技术鱼龙混杂, 光开发语言的衍生亚种就非常多, 打包器就需要能支持这些语言的编译器. 部分代码优化也在这里完成. 扩展性基本决定了一个打包器的命运和社区发展.</p><p>这两点基本所有的打包器都支持. 接下来说一些有差异化的地方.</p><h3 id=webpack>Webpack</h3><p>究极老牌的打包器了, Webpack在5版本之前是出了名的重和慢还有繁, 扩展性和社区都极佳, 基本所有的前端技术你都能在wp上找到对应的loader或者plugin. 也是目前最流行的打包器了. Webpack5出现了之后速度提升了很多. <code>webpack-chain</code>和<code>webpack-merge</code>使用这两个第三方包配合可以做到大部分的配置复用. 但是配置依然很重和繁琐这一点, 一直都没有很好的方案.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-javascript data-lang=javascript><span style=display:flex><span><span style=color:#66d9ef>var</span> <span style=color:#a6e22e>webpack</span> <span style=color:#f92672>=</span> <span style=color:#a6e22e>require</span>(<span style=color:#e6db74>&#39;webpack&#39;</span>);
</span></span><span style=display:flex><span><span style=color:#a6e22e>module</span>.<span style=color:#a6e22e>exports</span> <span style=color:#f92672>=</span> {
</span></span><span style=display:flex><span>     <span style=color:#a6e22e>entry</span><span style=color:#f92672>:</span><span style=color:#e6db74>&#39;./entry.js&#39;</span>, <span style=color:#75715e>//入口文件
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>     <span style=color:#a6e22e>output</span><span style=color:#f92672>:</span>{
</span></span><span style=display:flex><span>          <span style=color:#75715e>//node.js中__dirname变量获取当前模块文件所在目录的完整绝对路径 
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>          <span style=color:#a6e22e>path</span><span style=color:#f92672>:</span> <span style=color:#e6db74>&#34;dist&#34;</span>, <span style=color:#75715e>//输出位置
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>          <span style=color:#a6e22e>filename</span><span style=color:#f92672>:</span><span style=color:#e6db74>&#39;bundle.js&#39;</span> <span style=color:#75715e>//输入文件
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>     },
</span></span><span style=display:flex><span>     <span style=color:#a6e22e>module</span><span style=color:#f92672>:</span>{
</span></span><span style=display:flex><span>          <span style=color:#a6e22e>loaders</span><span style=color:#f92672>:</span>[
</span></span><span style=display:flex><span>               {
</span></span><span style=display:flex><span>                   <span style=color:#a6e22e>test</span><span style=color:#f92672>:</span><span style=color:#e6db74>/\.css$/</span>,<span style=color:#75715e>//支持正则
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>                   <span style=color:#a6e22e>loader</span><span style=color:#f92672>:</span><span style=color:#e6db74>&#39;style-loader!css-loader&#39;</span> 
</span></span><span style=display:flex><span>               },
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>               {
</span></span><span style=display:flex><span>                   <span style=color:#a6e22e>test</span><span style=color:#f92672>:</span> <span style=color:#e6db74>/\.vue$/</span>,
</span></span><span style=display:flex><span>                   <span style=color:#a6e22e>loader</span><span style=color:#f92672>:</span> <span style=color:#e6db74>&#39;vue-loader&#39;</span>
</span></span><span style=display:flex><span>               }
</span></span><span style=display:flex><span>          ]
</span></span><span style=display:flex><span>     },
</span></span><span style=display:flex><span><span style=color:#75715e>//其他解决方案配置
</span></span></span><span style=display:flex><span><span style=color:#75715e></span><span style=color:#a6e22e>resolve</span><span style=color:#f92672>:</span> {
</span></span><span style=display:flex><span>    <span style=color:#a6e22e>extensions</span><span style=color:#f92672>:</span> [<span style=color:#e6db74>&#39;&#39;</span>, <span style=color:#e6db74>&#39;.js&#39;</span>, <span style=color:#e6db74>&#39;.json&#39;</span>, <span style=color:#e6db74>&#39;.css&#39;</span>, <span style=color:#e6db74>&#34;vue&#34;</span>]<span style=color:#75715e>//添加在此的后缀所对应的文件可以省略后缀
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>},
</span></span><span style=display:flex><span>     <span style=color:#75715e>//插件
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>     <span style=color:#a6e22e>plugins</span><span style=color:#f92672>:</span>[
</span></span><span style=display:flex><span>          <span style=color:#66d9ef>new</span> <span style=color:#a6e22e>webpack</span>.<span style=color:#a6e22e>BannerPlugin</span>(<span style=color:#e6db74>&#39;This file is created by ly&#39;</span>)
</span></span><span style=display:flex><span>     ]
</span></span><span style=display:flex><span>}
</span></span></code></pre></div><h3 id=parcel>Parcel</h3><p>继Webpack之后新出现的打包器, 解决了Webpack的一个非常大的痛点, Parcel可以做到零配置启动.
自身就集成了parcel所有的东西, 你只需呀一个小小的index.html作为入口, 其他的全部解析都交给Parcel,
Parcel内部还集成了一个Js编译器, 并且由于该编译器使用的是Rust语言编写它的执行速度非常快.
理论上应该比esbuild还要快.
Parcel刚出现的时候风评并不好, 因为不支持source-map, 并且摇树还有bug..</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-javascript data-lang=javascript></code></pre></div><h3 id=sonwnpack>Sonwnpack</h3><p>时代在发展, 渐渐的浏览器也开始支持ESM了, Sonwnpack就是坐上了这个风口的打包器.
有了ESM, 你所有的JS模块都可以懒加载的方式载入到页面中. 并且你的第一次开发服务器启动也不需要编译所有依赖的JS代码.
顺势的, Sonwnpack中就出现了一个<code>HMR(热模块替换)</code>的概念</p><blockquote>
<p>热模块替换 (HMR) 是一种在不触发整个页面刷新的情况下将文件更新推送到浏览器的能力。想象一下更改一些 CSS，点击保存，然后立即看到您的更改反映在页面上而无需刷新。那是HMR。然而，Snowpack 利用 ESM 进行非捆绑开发的能力引入了近乎即时的单个文件构建，只需 10-25 毫秒即可在浏览器中加载和更新。</p></blockquote><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-javascript data-lang=javascript><span style=display:flex><span><span style=color:#75715e>/** @type {import(&#34;snowpack&#34;).SnowpackUserConfig } */</span>
</span></span><span style=display:flex><span><span style=color:#a6e22e>module</span>.<span style=color:#a6e22e>exports</span> <span style=color:#f92672>=</span> {
</span></span><span style=display:flex><span>  <span style=color:#a6e22e>mount</span><span style=color:#f92672>:</span> {
</span></span><span style=display:flex><span>    <span style=color:#a6e22e>test</span><span style=color:#f92672>:</span> { <span style=color:#a6e22e>url</span><span style=color:#f92672>:</span> <span style=color:#e6db74>&#39;/&#39;</span>, <span style=color:#66d9ef>static</span><span style=color:#f92672>:</span> <span style=color:#66d9ef>true</span> },
</span></span><span style=display:flex><span>    <span style=color:#66d9ef>public</span><span style=color:#f92672>:</span> { <span style=color:#a6e22e>url</span><span style=color:#f92672>:</span> <span style=color:#e6db74>&#39;/&#39;</span>, <span style=color:#66d9ef>static</span><span style=color:#f92672>:</span> <span style=color:#66d9ef>true</span> },
</span></span><span style=display:flex><span>    <span style=color:#a6e22e>src</span><span style=color:#f92672>:</span> { <span style=color:#a6e22e>url</span><span style=color:#f92672>:</span> <span style=color:#e6db74>&#39;/_dist_&#39;</span> },
</span></span><span style=display:flex><span>  },
</span></span><span style=display:flex><span>  <span style=color:#a6e22e>plugins</span><span style=color:#f92672>:</span> [
</span></span><span style=display:flex><span>    <span style=color:#e6db74>&#39;@snowpack/plugin-webpack&#39;</span>,
</span></span><span style=display:flex><span>    <span style=color:#e6db74>&#39;@snowpack/plugin-vue&#39;</span>,
</span></span><span style=display:flex><span>    <span style=color:#e6db74>&#39;@snowpack/plugin-sass&#39;</span>,
</span></span><span style=display:flex><span>    <span style=color:#e6db74>&#39;@snowpack/plugin-dotenv&#39;</span>,
</span></span><span style=display:flex><span>    <span style=color:#75715e>// [&#34;@snowpack/plugin-build-script&#34;, { &#34;cmd&#34;: &#34;postcss&#34;, &#34;input&#34;: [&#34;.css&#34;], &#34;output&#34;: [&#34;.css&#34;] }]//,
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>  ],
</span></span><span style=display:flex><span>};
</span></span></code></pre></div><h3 id=vite>Vite</h3><p>vite的起步还比较晚, 它的部分开发灵感来自Sonwnpack, 同时vite也支持HMR.
比较特别的是Vite自带的编译器是ESBuild, 在官方banner上速度<strong>极其夸张的一个编译器</strong>.
配置文件时vite的优点,大部分的插件即插即用, 以及配置文件的写法修复了很多以前打包器的缺点, 可以非常灵活.
目前Vite的扩展现在还比较少, 以后可以期待一下.</p><blockquote>
<p>ESBuild的官方宣称: 基准测试通过将three.js库复制 10 次并从头开始构建单个包来近似大型 JavaScript 代码库，而无需任何缓存. Webpack5 = 41.53s, rollup + terser = 34.95s, parcel2 = 32.48s, esbuild = 0.33s. 这个速度是传统打包器的100倍.</p></blockquote><blockquote>
<p>然而在实测中, 我在当前的Webpack中引入了esbuild, 来代替以前的babel和tsc, 时间也只省下了5-10s, 并没有那么夸张, 可能是Webpack的loader调用导致的瓶颈.</p></blockquote><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-javascript data-lang=javascript><span style=display:flex><span><span style=color:#75715e>// vite.config.js
</span></span></span><span style=display:flex><span><span style=color:#75715e></span><span style=color:#66d9ef>import</span> { <span style=color:#a6e22e>defineConfig</span> } <span style=color:#a6e22e>from</span> <span style=color:#e6db74>&#39;vite&#39;</span>
</span></span><span style=display:flex><span><span style=color:#66d9ef>import</span> <span style=color:#a6e22e>react</span> <span style=color:#a6e22e>from</span> <span style=color:#e6db74>&#39;@vitejs/plugin-react&#39;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#66d9ef>export</span> <span style=color:#66d9ef>default</span> <span style=color:#a6e22e>defineConfig</span>({
</span></span><span style=display:flex><span>  <span style=color:#a6e22e>plugins</span><span style=color:#f92672>:</span> [<span style=color:#a6e22e>react</span>()]
</span></span><span style=display:flex><span>})
</span></span></code></pre></div><h3 id=rollup>Rollup</h3><p>Rollup是个非传统意义上的打包器, 它主要面向的是类库的前端开发者. Rollup的配置文件的繁琐程度比较折中.
Rollup似乎没有对分包的支持, 理念就是将小块代码打包成大块的复杂代码,放在一个文件中.
Rollup自带的功能也非常少, 甚至不支持node模块解析. 大部分都需要依赖插件完成.</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-javascript data-lang=javascript><span style=display:flex><span><span style=color:#75715e>// rollup.config.js
</span></span></span><span style=display:flex><span><span style=color:#75715e></span><span style=color:#66d9ef>import</span> <span style=color:#a6e22e>json</span> <span style=color:#a6e22e>from</span> <span style=color:#e6db74>&#39;rollup-plugin-json&#39;</span>;
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#66d9ef>export</span> <span style=color:#66d9ef>default</span> {
</span></span><span style=display:flex><span>  <span style=color:#a6e22e>input</span><span style=color:#f92672>:</span> <span style=color:#e6db74>&#39;src/main.js&#39;</span>,
</span></span><span style=display:flex><span>  <span style=color:#a6e22e>output</span><span style=color:#f92672>:</span> {
</span></span><span style=display:flex><span>    <span style=color:#a6e22e>file</span><span style=color:#f92672>:</span> <span style=color:#e6db74>&#39;bundle.js&#39;</span>,
</span></span><span style=display:flex><span>    <span style=color:#a6e22e>format</span><span style=color:#f92672>:</span> <span style=color:#e6db74>&#39;cjs&#39;</span>
</span></span><span style=display:flex><span>  },
</span></span><span style=display:flex><span>  <span style=color:#a6e22e>plugins</span><span style=color:#f92672>:</span> [ <span style=color:#a6e22e>json</span>() ]
</span></span><span style=display:flex><span>};
</span></span></code></pre></div><h2 id=关于编译器>关于编译器</h2><p>目前大部分前端的编译器非常混杂, 基本是各做各的, JS的编译器的Babel是不二之选, 所有ES标准以及Typescript甚至Flow和coffeescript,Babel都能编译.
也支持一些<code>async do {}</code>这种奇怪的语法糖. ESBuild和兴起的SWC是针对速度进行优化. 这里也没什么好说的.</p></section><footer class=article-footer>
<section class=article-tags>
<a href=/tags/build/>build</a>
</section><section class=article-lastmod><svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-clock" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentcolor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><circle cx="12" cy="12" r="9"/><polyline points="12 7 12 12 15 15"/></svg>
<span>
Last updated on Mar 10, 2022 14:46 CST
</span>
</section></footer></article><aside class=related-contents--wrapper>
<h2 class=section-title>Related contents</h2><div class=related-contents>
<div class="flex article-list--tile">
<article>
<a href=/blog/gradle-build-for-idiotc4t/>
<div class=article-details>
<h2 class=article-title>记录一次Gradle构建的困难</h2></div></a>
</article></div></div></aside><div id=gitalk-container></div><link rel=stylesheet href=https://cdn.jsdelivr.net/npm/gitalk@1.7.2/dist/gitalk.css>
<script src=https://cdn.jsdelivr.net/npm/gitalk@1.7.2/dist/gitalk.min.js></script>
<script src=https://cdn.jsdelivr.net/npm/blueimp-md5@2.18.0/js/md5.min.js></script>
<script>const gitalk=new Gitalk({clientID:"97eb9ce8ac126f0c7833",clientSecret:"5da440441b500b0b016928640712a1b1a03a5f8f",repo:"sdttttt/sdttttt.github.io",owner:"sdttttt",admin:["sdttttt"],distractionFreeMode:!1,id:md5(location.pathname)});(function(){if(["localhost","127.0.0.1"].indexOf(window.location.hostname)!=-1){document.getElementById("gitalk-container").innerHTML="Gitalk comments not available by default when the website is previewed locally.";return}gitalk.render("gitalk-container")})()</script>
<footer class=site-footer>
<section class=copyright>
&copy;
2022 SDTTTTT
</section><section class=powerby>
Built with <a href=https://gohugo.io/ target=_blank rel=noopener>Hugo</a> <br>
Theme <b><a href=https://github.com/CaiJimmy/hugo-theme-stack target=_blank rel=noopener data-version=3.10.0>Stack</a></b> designed by <a href=https://jimmycai.com target=_blank rel=noopener>Jimmy</a>
</section></footer><div class=pswp tabindex=-1 role=dialog aria-hidden=true>
<div class=pswp__bg></div><div class=pswp__scroll-wrap>
<div class=pswp__container>
<div class=pswp__item></div><div class=pswp__item></div><div class=pswp__item></div></div><div class="pswp__ui pswp__ui--hidden">
<div class=pswp__top-bar>
<div class=pswp__counter></div><button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
<button class="pswp__button pswp__button--share" title=Share></button>
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
<div class=pswp__preloader>
<div class=pswp__preloader__icn>
<div class=pswp__preloader__cut>
<div class=pswp__preloader__donut></div></div></div></div></div><div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
<div class=pswp__share-tooltip></div></div><button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
</button>
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
</button>
<div class=pswp__caption>
<div class=pswp__caption__center></div></div></div></div></div><script src=https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js integrity="sha256-ePwmChbbvXbsO02lbM3HoHbSHTHFAeChekF1xKJdleo=" crossorigin=anonymous defer></script><script src=https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js integrity="sha256-UKkzOn/w1mBxRmLLGrSeyB4e1xbrp4xylgAWb3M42pU=" crossorigin=anonymous defer></script><link rel=stylesheet href=https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.css integrity="sha256-c0uckgykQ9v5k+IqViZOZKc47Jn7KQil4/MP3ySA3F8=" crossorigin=anonymous><link rel=stylesheet href=https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.css integrity="sha256-SBLU4vv6CA6lHsZ1XyTdhyjJxCjPif/TRkjnsyGAGnE=" crossorigin=anonymous>
</main></div><script src=https://cdn.jsdelivr.net/npm/node-vibrant@3.1.5/dist/vibrant.min.js integrity="sha256-5NovOZc4iwiAWTYIFiIM7DxKUXKWvpVEuMEPLzcm5/g=" crossorigin=anonymous></script><script type=text/javascript src=/ts/main.js defer></script>
<script>(function(){const e=document.createElement("link");e.href="https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&display=swap",e.type="text/css",e.rel="stylesheet",document.head.appendChild(e)})()</script>
</body></html>